<?php

/**
 * DB类 Yjnic_Db_Pdo
 *
 * @author prettyyjnic <prettyyjnic@qq.com> 20151027
 */
class Yjnic_Db_Pdo {

    /**
     * @var array $_configs 数据库配置 
     */
    protected $_configs = array();
    protected $_pdo = NULL;
    protected $_query_ins = NULL;
    protected $_exec_ins = NULL;
    protected $_where = '';
    protected $_last_sql = '';
    protected $_last_type = 0;// 0 = query
    protected $_order = '';

    /**
     * @param array $configs 数据库配置 
     * @param boolean $debug 是否开启调试模式
     */
    public function __construct($configs) {
        if (empty($configs)) {
            throw new PhalApi_Exception_InternalServerError(
                T('no such db:{db} in servers', array('db' => $configs['dbname'])));
        }  
        $this->_configs = $configs;        
    }
    
    /**
     * beginTransaction
     */
    public function beginTransaction(){
        return $this->_pdo->beginTransaction();
    }

    /**
     * commit
     */
    public function commit(){
        return $this->_pdo->commit();
    }

    /**
     * rollback
     */
    public function rollback(){
        return $this->_pdo->rollback();
    }

    public function getLastSql(){
        if ($this->_last_type == 0) {
            return $this->_getQueryIns()->getLastSql();
        }else{
            return $this->_getExecIns()->getLastSql();
        }
    }

    /**
     * 获取 PDO连接
     * @return PDO
     */
    protected function _connect() {
        if ($this->_pdo == NULL) {            
            try {
                $db_config = $this->_configs;
                $dsn = sprintf('mysql:dbname=%s;host=%s;port=%d',
                    $db_config['dbname'], 
                    $db_config['host'], 
                    $db_config['port']
                );
                $charset = $db_config['charset'];
                $db_params = array(
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,//让其抛出异常
                );
                if (isset($db_config['pconnect'])&&$db_config['pconnect']==true) {//长链接
                    $db_params[PDO::ATTR_PERSISTENT] = true;
                }
                $this->_pdo = new PDO(
                    $dsn,
                    $db_config['user'],
                    $db_config['password'],
                    $db_params
                );
                $this->_pdo->exec("SET NAMES '{$charset}'");
            } catch (PDOException $ex) {
                //异常时，接口异常返回，并隐藏数据库帐号信息                
                throw new Yjnic_Db_Exception('can not connect to database:'.$db_config['dbname'], 500); 
            }
        }
        return $this->_pdo;
    }

    /**
     * 获取pdo_query
     */
    protected function _getQueryIns(){
        if ($this->_query_ins == NULL) {
            $pdo = $this->_connect();
            $this->_query_ins = new Yjnic_Db_Query($pdo, $this->_configs['debug']);
        }
        return $this->_query_ins;
    }

    /**
     * 获取pdo_exec
     */
    protected function _getExecIns(){
        if ($this->_exec_ins == NULL) {
            $pdo = $this->_connect();
            $this->_exec_ins = new Yjnic_Db_Execute($pdo, $this->_configs['debug']);
        }
        return $this->_exec_ins;
    }

    public function __call($method, $args){
        if (strpos($method, 'fetch') !== false || strpos($method, 'get') !== false) {
            $this->_last_type = 0;
            $query_ins = $this->_getQueryIns();
            return call_user_func_array(array($query_ins, $method), $args);
        }else{
            $this->_last_type = 1;
            $exec_ins = $this->_getExecIns();
            return call_user_func_array(array($exec_ins, $method), $args);
        }  
    }

    /**
     * 断开数据库链接
     */
    public function __destruct(){
        $this->_pdo = NULL;
    }
}